﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using StockReportScanner.Engine;
using mshtml;
using System.Xml;
using System.Threading;

namespace StockReportScanner
{
    public partial class MainForm : Form
    {
        private enum LISTITEM_STATUS
        {
            ERROR = 0,
            INFO = 1
        }

        static String FILE_URL_CONFIG = Application.StartupPath + "\\url.cfg";
        static String FILE_SEARCH_CONFIG = Application.StartupPath + "\\search.cfg";
        static String FILE_SAVE_RESULT = Application.StartupPath + "\\result.csv";

        const int ERROR_LOAD_SYMBOL_SLEEP = 20 * 1000;//20s
        const int ERROR_READ_REPORT_SLEEP = 5 * 1000;//5s
        //Thread programming http://msdn.microsoft.com/en-us/library/7a2f3ay4(v=vs.90).aspx
        private Thread scanReportThread;
        private volatile bool bStop = false;

        
        public MainForm()
        {
            InitializeComponent();
        }

        #region Item event handler
        private void toolbarMain_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem == this.toolStripButton_Scan)
                OnScan();
            else if (e.ClickedItem == this.toolStripButton_Stop)
                OnStop();            
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OnExit();
        }

        private void scanToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OnScan();
        }

        private void stopToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OnStop();
        }
        
        #endregion //Item event handler

        #region Item Action
        private void OnExit()
        {
            MessageBox.Show("Exit");
        }

        private void OnScan()
        {
            bStop = false;
            scanReportThread = new Thread(new ThreadStart(ScanReport));
            scanReportThread.Start();
            EnableScan(false);
        }

        private void OnStop()
        {
            bStop = true;
            //scanReportThread.Join();
            EnableScan(true);
        }
        #endregion //Item Action

        private void MainForm_Load(object sender, EventArgs e)
        {
            this.listView_Status.Columns[0].Width = -2;// listView_Status.Width;
            this.listView_Result.Columns[0].Width = -2;// listView_Status.Width;

            EnableScan(true);

            GetData.LoadUrlConfig(FILE_URL_CONFIG);
            GetData.LoadConfigSearch(FILE_SEARCH_CONFIG);
            GetData.LoadStoreSymbol(FILE_SAVE_RESULT);
            
            //GetData.SearchReport("AAM", StockType.HOSE);
            //GetData.SearchReport("AAA", StockType.HASTC);
        }

        private void ScanReport()
        {
            GetData.ListSymbol.Clear();
            while (true) //loop until success
            {
                //Hose
                try
                {
                    AddStatusItem(NewStatusItem("Load Hose symbol", LISTITEM_STATUS.INFO));
                    GetData.LoadStockList(StockType.HOSE);                   
                }
                catch
                {
                    AddStatusItem(NewStatusItem("Error loading Hose symbol, trying to reload", LISTITEM_STATUS.ERROR));
                    GetData.ListSymbol.Clear();
                    Thread.Sleep(ERROR_LOAD_SYMBOL_SLEEP);
                    continue;
                }

                //Hastc
                try
                {
                    AddStatusItem(NewStatusItem("Load Hastc symbol", LISTITEM_STATUS.INFO));
                    GetData.LoadStockList(StockType.HASTC);
                }
                catch
                {
                    AddStatusItem(NewStatusItem("Error loading Hastc symbol, trying to reload", LISTITEM_STATUS.ERROR));
                    GetData.ListSymbol.Clear();
                    Thread.Sleep(ERROR_LOAD_SYMBOL_SLEEP);
                    continue;
                }

                if ( GetData.ListSymbol.Count > 0)
                    break;
               
            }

            while (!bStop)
            {
                Dictionary<String, StockItem> newSymbols = new Dictionary<string, StockItem>();
                foreach (StockItem stockItem in GetData.ListSymbol.Values)
                {
                    if (bStop)
                        break;

                    while (true)//loop until success
                    {
                        try
                        {
                            AddStatusItem(NewStatusItem("Read report for symbol: " + stockItem.Symbol, LISTITEM_STATUS.INFO));
                            if (GetData.SearchReport(stockItem.Symbol, stockItem.StockType))
                            {
                                stockItem.HasReport = true;

                                if (GetData.ListStoreSymbol.ContainsKey(stockItem.Symbol))
                                {
                                    StockItem saveItem = GetData.ListStoreSymbol[stockItem.Symbol];
                                    if (saveItem.HasReport != stockItem.HasReport)
                                    {
                                        //Notify result
                                        AddResultItem(NewResultItem(stockItem));
                                        newSymbols.Add(stockItem.Symbol, stockItem);
                                    }
                                }
                                else
                                {
                                    //Notify result
                                    AddResultItem(NewResultItem(stockItem));
                                    newSymbols.Add(stockItem.Symbol, stockItem);
                                }
                            }
                        }
                        catch
                        {
                            AddStatusItem(NewStatusItem("Error read symbol: " + stockItem.Symbol + ". Trying again", LISTITEM_STATUS.ERROR));
                            Thread.Sleep(ERROR_READ_REPORT_SLEEP);
                            continue;
                        }
                        break;
                    }
                    
                }
                
                //Save 
                GetData.CloneSymbolToStore();
                GetData.SaveStoreSymbol(FILE_SAVE_RESULT);
                
                String fileName = String.Format("result_{0:yyyy_MM_dd_HH_mm_ss}", DateTime.Now);
                String resultFile = String.Format("{0}\\{1}.csv", Application.StartupPath, fileName);
                GetData.SaveStoreSymbol(resultFile);

                fileName = String.Format("new_{0:yyyy_MM_dd_HH_mm_ss}", DateTime.Now);
                String newFile = String.Format("{0}\\{1}.csv", Application.StartupPath, fileName);
                GetData.SaveDictionary(newFile, newSymbols);

                GetData.SendReport(newSymbols);

                ClearStatusItem();
                ClearResultItem();
            }
        }

        private void EnableScan(bool bEnable)
        {
            toolStripButton_Scan.Enabled = scanToolStripMenuItem.Enabled = bEnable;
            toolStripButton_Stop.Enabled = stopToolStripMenuItem.Enabled = !bEnable;
        }

        private void MainForm_SizeChanged(object sender, EventArgs e)
        {
            this.listView_Status.Columns[0].Width = -2;// listView_Status.Width;
            this.listView_Result.Columns[0].Width = -2;// listView_Status.Width;

        }

        #region List Status
        private delegate void AddStatusItemCallback(ListViewItem o);

        private void AddStatusItem(ListViewItem o)
        {
            if (this.listView_Status.InvokeRequired)
            {
                AddStatusItemCallback d = new AddStatusItemCallback(AddStatusItem);
                this.Invoke(d, new object[] { o });
            }
            else
            {
                this.listView_Status.Items.Add(o);
                this.listView_Status.EnsureVisible(listView_Status.Items.Count - 1);
            }
        }

        private delegate void ClearStatusItemCallback();

        private void ClearStatusItem()
        {
            if (this.listView_Status.InvokeRequired)
            {
                ClearStatusItemCallback d = new ClearStatusItemCallback(ClearStatusItem);
                this.Invoke(d);
            }
            else
            {
                this.listView_Status.Items.Clear();
            }
        }

        private ListViewItem NewStatusItem(String text, LISTITEM_STATUS status)
        {
            ListViewItem item = new ListViewItem(text);
            item.ImageIndex = (int)status;
            return item;
        }

        #endregion  

        #region List Result
        private delegate void AddResultItemCallback(ListViewItem o);

        private void AddResultItem(ListViewItem o)
        {
            if (this.listView_Status.InvokeRequired)
            {
                AddResultItemCallback d = new AddResultItemCallback(AddResultItem);
                this.Invoke(d, new object[] { o });
            }
            else
            {
                this.listView_Result.Items.Add(o);
                this.listView_Result.EnsureVisible(listView_Result.Items.Count - 1);
            }
        }

        private delegate void ClearResultItemCallback();

        private void ClearResultItem()
        {
            if (this.listView_Result.InvokeRequired)
            {
                ClearResultItemCallback d = new ClearResultItemCallback(ClearResultItem);
                this.Invoke(d);
            }
            else
            {
                this.listView_Result.Items.Clear();
            }
        }

        private ListViewItem NewResultItem(StockItem stockItem)
        {
            String textItem = String.Format("{0}: {1}", stockItem.StockType.ToString(), stockItem.Symbol);
            ListViewItem item = new ListViewItem(textItem);            
            return item;
        }

        #endregion  



        
    }
}
